package main

import (
	"go/ast"
	"log"
	"unsafe"
)

type itab struct {
	inter *ast.InterfaceType
	fun [1]uintptr
}
type iface struct {
	//类型信息
	tab *itab
	//实际对象指针
	data unsafe.Pointer
}

type data struct {
	x int
}

type TestError struct {}

func (* TestError) Error() string  {
	return  "error"
}

func test(x int) (int,error)  {
	//错误做法 err并不为nil
	//var err *TestError
	//if x < 0 {
	//	err = new(TestError)
	//	x =0
	//} else {
	//	x +=100
	//}
	//return x,err

	//正确做法 明确返回nil
	if x < 0 {
		return 0,new(TestError)
	}
	return x+100,nil
}

func main() {
	d := data{100}
	//将对象复制给接口 复制的对象不能修改
	var  t interface{} =d
	println(t.(data).x)
	//不能赋值 t.(data).x =100
	var t1 interface{} = &d
	println(t1.(*data).x)
	t1.(*data).x = 30
	println(t1.(*data).x)


	//只有当接口变量内部的两个指针（itab,data）都为nil时，接口才为nil
	var a interface{} = nil
	// data为nil但是b还包含类的信息
	var b interface{} = (*int)(nil)
	println(a==nil,b==nil) //true false


	x,err :=test(100)
	if err != nil {
		log.Fatalln("err != nil")
	}

	println(x)
}
